<template>
  <div class="page-container">
    <!--表格内容栏-->
    <ac-table
      ref="dataTable"
      pkName="id"
      :filters="filters"
      :filterFields="filterFields"
      :columns="columns"
      :checkRowOpShow="checkRowOpShow"
      @handleTableOperator="handleTableOperator"
      @handleCellOperator="handleCellOperator"
    />

    <!--新增/编辑/查看界面-->
    <el-dialog
      width="650px"
      v-model="dialogVisible"
      :title="dialogTitle"
      :close-on-click-modal="false"
      destroy-on-close
      draggable
    >
      <el-form
        :model="formData"
        ref="dataForm"
        label-width="120px"
        label-position="right"
        :disabled="!dialogEdit"
        :rules="rules"
        :hide-required-asterisk="!dialogEdit"
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="备份名称" prop="name">
              <el-input v-model="formData.name"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备份类型" prop="type">
              <ac-checkbox v-model="formData.type" options="系统配置,子系统配置,子系统数据" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button
          v-if="dialogEdit"
          size="default"
          type="info"
          @click="dialogVisible=false"
        >取消</el-button>
        <el-button
          v-if="dialogEdit"
          size="default"
          type="primary"
          @click="submitForm"
          :loading="editLoading"
        >备份</el-button>
      </template>
    </el-dialog>

    <!--新增/编辑/查看界面-->
    <el-dialog
      v-model="customVisible"
      :title="customTitle"
      :close-on-click-modal="false"
      destroy-on-close
      draggable
      fullscreen
    >
      <el-form
        :model="customData"
        ref="customForm"
        label-width="120px"
        label-position="right"
        :rules="rules"
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="备份名称" prop="name">
              <el-input v-model="customData.name"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备份系统" prop="subsystemIds">
              <el-checkbox-group v-model="customData.subsystemIds">
                <el-checkbox
                  v-for="subsystem in subsystemList"
                  :key="subsystem.id"
                  :label="subsystem.name"
                  :value="subsystem.id"
                />
              </el-checkbox-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-tabs v-model="tabName">
          <el-tab-pane name="model" label="数据模型">
            <el-tree
              ref="modelTree"
              class="tree"
              node-key="id"
              v-loading="modelLoading"
              element-loading-text="数据加载中..."
              :data="modelTreeData"
              :props="treeProps"
              :highlight-current="true"
              :default-expanded-keys="['0']"
              :show-checkbox="true"
            >
              <template v-slot="{ node, data }">
                <div class="node-item">
                  <div v-if="data.type === 'folder'" class="icon">
                    <ac-icon v-if="node.expanded" style="color: orange" iconId="018dc9c3efedbb59d0b3" />
                    <ac-icon v-else style="color: orange" iconId="018dc9c3efed6d208a59" />
                  </div>
                  <div v-else class="icon">
                    <ac-icon v-if="data.type === 'model'" iconId="018dc9c3efb74ac607cb" style="color: #0085f6" />
                  </div>
                  <div class="node-label" :title="data.text"><span>{{data.text}}</span></div>
                </div>
              </template>
            </el-tree>
          </el-tab-pane>
          <el-tab-pane name="modelData" label="数据">
            <el-tree
              ref="modelDataTree"
              class="tree"
              node-key="id"
              v-loading="modelLoading"
              element-loading-text="数据加载中..."
              :data="modelTreeData"
              :props="treeProps"
              :highlight-current="true"
              :default-expanded-keys="['0']"
              :show-checkbox="true"
            >
              <template v-slot="{ node, data }">
                <div class="node-item">
                  <div v-if="data.type === 'folder'" class="icon">
                    <ac-icon v-if="node.expanded" style="color: orange" iconId="018dc9c3efedbb59d0b3" />
                    <ac-icon v-else style="color: orange" iconId="018dc9c3efed6d208a59" />
                  </div>
                  <div v-else class="icon">
                    <ac-icon v-if="data.type === 'model'" iconId="018dc9c3efb74ac607cb" style="color: #0085f6" />
                  </div>
                  <div class="node-label" :title="data.text"><span>{{data.text}}</span></div>
                </div>
              </template>
            </el-tree>
          </el-tab-pane>
          <el-tab-pane name="script" label="脚本">
            <el-tree
              ref="scriptTree"
              class="tree"
              node-key="id"
              v-loading="scriptLoading"
              element-loading-text="数据加载中..."
              :data="scriptTreeData"
              :props="treeProps"
              :highlight-current="true"
              :default-expanded-keys="['0']"
              :show-checkbox="true"
            >
              <template v-slot="{ node, data }">
                <div class="node-item">
                  <div v-if="data.type === 'folder'" class="icon">
                    <ac-icon v-if="node.expanded" color="orange" iconId="018dc9c3efedbb59d0b3" />
                    <ac-icon v-else color="orange" iconId="018dc9c3efed6d208a59" />
                  </div>
                  <div v-else-if="data.type === 'script'" class="icon">
                    <ac-icon color="#117fe8" iconId="018dc9c3efb74ac607cb" />
                  </div>
                  <div class="node-label" :title="data.text"><span>{{data.text}}</span></div>
                </div>
              </template>
            </el-tree>
          </el-tab-pane>
          <el-tab-pane name="view" label="视图">
            <el-tree
              ref="viewTree"
              class="tree"
              node-key="id"
              v-loading="viewLoading"
              element-loading-text="数据加载中..."
              :data="viewTreeData"
              :props="treeProps"
              :highlight-current="true"
              :default-expanded-keys="['0']"
              :show-checkbox="true"
            >
              <template v-slot="{ node, data }">
                <div class="node-item">
                  <div v-if="data.type === 'folder'" class="icon">
                    <ac-icon v-if="node.expanded" color="orange" iconId="018dc9c3efedbb59d0b3" />
                    <ac-icon v-else color="orange" iconId="018dc9c3efed6d208a59" />
                  </div>
                  <div v-else-if="data.type === 'view'" class="icon">
                  <ac-icon color="#117fe8" iconId="018dc9c3efb74ac607cb" />
                  </div>
                  <div class="node-label" :title="data.text"><span>{{data.text}}</span></div>
                </div>
              </template>
            </el-tree>
          </el-tab-pane>
          <el-tab-pane name="page" label="页面">
            <el-tree
              ref="pageTree"
              class="tree"
              node-key="id"
              v-loading="pageLoading"
              element-loading-text="数据加载中..."
              :data="pageTreeData"
              :props="treeProps"
              :highlight-current="true"
              :default-expanded-keys="['0']"
              :show-checkbox="true"
            >
              <template v-slot="{ node, data }">
                <div class="node-item">
                  <div v-if="data.type === 'folder'" class="icon">
                    <ac-icon v-if="node.expanded" color="orange" iconId="018dc9c3efedbb59d0b3" />
                    <ac-icon v-else color="orange" iconId="018dc9c3efed6d208a59" />
                  </div>
                  <div v-else-if="data.type === 'page'" class="icon">
                    <ac-icon color="#117fe8" iconId="018dc9c3efb74ac607cb" />
                  </div>
                  <div class="node-label" :title="data.text"><span>{{data.text}}</span></div>
                </div>
              </template>
            </el-tree>
          </el-tab-pane>
          <el-tab-pane name="flow" label="流程">
            <el-checkbox-group v-model="flowIds">
              <el-checkbox
                v-for="flow in flowData"
                :key="flow.id"
                :label="flow.name"
                :value="flow.id"
              />
            </el-checkbox-group>
          </el-tab-pane>
          <el-tab-pane name="dictionary" label="字典">
            <el-tree
              ref="dictionaryTree"
              class="tree"
              node-key="id"
              v-loading="dictionaryLoading"
              element-loading-text="数据加载中..."
              :data="dictionaryTreeData"
              :props="treeProps"
              :highlight-current="true"
              :default-expanded-keys="['0']"
              :show-checkbox="true"
            >
              <template v-slot="{ node, data }">
                <div class="node-item">
                  <span class="icon">
                    <ac-icon v-if="node.expanded" color="orange" iconId="018dc9c3efedbb59d0b3" />
                    <ac-icon v-else color="orange" iconId="018dc9c3efedbb59d0b3" />
                  </span>
                  <span class="node-label" :title="data.text"><span>{{data.text}}</span></span>
                </div>
              </template>
            </el-tree>
          </el-tab-pane>
          <el-tab-pane name="sequence" label="序号">
            <el-checkbox-group v-model="sequenceIds">
              <el-checkbox
                v-for="sequence in sequenceData"
                :key="sequence.id"
                :label="sequence.name"
                :value="sequence.id"
              />
            </el-checkbox-group>
          </el-tab-pane>
        </el-tabs>
      </el-form>
      <template #footer>
        <el-button
          size="default"
          type="info"
          @click="customVisible=false"
        >取消</el-button>
        <el-button
          size="default"
          type="primary"
          @click="submitCustomForm"
          :loading="editLoading"
        >备份</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import api from '@/http/api';

const filters = ref({
  name: ''
});

const filterFields = ref([
  {prop: "name", label: "名称"}
]);

const columns = ref([
  {prop: "name", label: "备份名称", minWidth: 160},
  {prop: "type", label: "备份类型", minWidth: 120},
  {prop: "mode", label: "备份方式", width: 120},
  {prop: "createTime", label: "创建时间", width: 160, type: 'datetime'},
]);

const rules = ref({
  name: [
    {required: true, message: '请输入名称', trigger: 'change'},
    {max: 100, message: '长度必须小于等于 100 个字符！', trigger: 'change'}
  ],
  type: [
    {required: true, message: '请输入备份类型', trigger: 'change'},
    {max: 100, message: '长度必须小于等于 100 个字符！', trigger: 'change'}
  ],
  mode: [
    {required: true, message: '请输入备份方式', trigger: 'change'},
    {max: 10, message: '长度必须小于等于 10 个字符！', trigger: 'change'}
  ],
  fileId: [
    {required: true, message: '请输入备份文件ID', trigger: 'change'},
    {max: 32, message: '长度必须小于等于 32 个字符！', trigger: 'change'}
  ],
});

const dataTable = ref();
const dataForm = ref();
const formData = ref({});
const dialogTitle = ref('');
const dialogVisible = ref(false);
const editLoading = ref(false);
const dialogEdit = ref(false);

const customForm = ref();
const customData = ref({});
const customTitle = ref('');
const customVisible = ref(false);
const tabName = ref('model');
const treeProps = ref({
  children: 'children',
  label: 'text'
});
const subsystemList = ref([]);
const modelTree = ref();
const modelDataTree = ref();
const modelTreeData = ref([]);
const modelLoading = ref(false);

const scriptTree = ref();
const scriptTreeData = ref([]);
const scriptLoading = ref(false);

const viewTree = ref();
const viewTreeData = ref([]);
const viewLoading = ref(false);

const pageTree = ref();
const pageTreeData = ref([]);
const pageLoading = ref(false);

const dictionaryTree = ref();
const dictionaryTreeData = ref([]);
const dictionaryLoading = ref(false);

const flowIds = ref([]);
const flowData = ref([]);
const flowLoading = ref(false);

const sequenceIds = ref([]);
const sequenceData = ref([]);
const sequenceLoading = ref(false);

const checkRowOpShow = (op, row) => {
  return (op.buttonType === "download" && row.fileId) || op.buttonType !== "download";
};

const handleCellOperator = (property, value, row) => {
  formData.value = Object.assign({}, row);
  dialogVisible.value = true;
  dialogEdit.value = false;
  dialogTitle.value = "查看";

  nextTick(() => {
    dataForm.value && dataForm.value.clearValidate();
  });
};

const handleTableOperator = (button, row) => {
  if (button.buttonType === "backup") {
    dialogVisible.value = true;
    dialogEdit.value = true;
    dialogTitle.value = button.name;
    formData.value = {
      type: "系统配置,子系统配置",
      mode: "手动备份",
      button: button
    };
    nextTick(() => {
      dataForm.value && dataForm.value.clearValidate();
    });
  } else if (button.buttonType === "custom") {
    customVisible.value = true;
    customTitle.value = button.name;
    customData.value = {
      type: "自定义",
      mode: "手动备份",
      button: button
    };
    loadData();
    nextTick(() => {
      dataForm.value && dataForm.value.clearValidate();
    });
  } else if (button.buttonType === "download") {
    api.downloadFileLocal(row.fileId);
  }
};

const submitForm = () => {
  dataForm.value && dataForm.value.validate((valid) => {
    if (valid) {
      ElMessageBox.confirm('请确认是否备份？', '提示', {type: 'info'}).then(() => {
        editLoading.value = true;
        api.post(formData.value.button.dataDestUrl, formData.value).then(res => {
          ElMessage.success(res.message);
          dialogVisible.value = false;
          dataTable.value.findPage();
          editLoading.value = false;
        }).catch(() => {
          editLoading.value = false;
        });
      }).catch(() => {});
    } else {
      ElMessage.error('数据录入不正确，请重新检查！');
    }
  })
};

const submitCustomForm = () => {
  customForm.value && customForm.value.validate((valid) => {
    if (valid) {
      ElMessageBox.confirm('请确认是否备份？', '提示', {type: 'info'}).then(() => {
        editLoading.value = true;

        customData.value.model = getTreeData('model', modelTree.value.getCheckedNodes(false, true));
        customData.value.modelIds = getTreeData('model', modelDataTree.value.getCheckedNodes(false, true))['modelIds'];
        customData.value.script = getTreeData('script', scriptTree.value.getCheckedNodes(false, true));
        customData.value.view = getTreeData('view', viewTree.value.getCheckedNodes(false, true));
        customData.value.page = getTreeData('page', pageTree.value.getCheckedNodes(false, true));
        customData.value.dictionaryIds = getTreeData('', dictionaryTree.value.getCheckedNodes(false, true));
        customData.value.flowIds = flowIds.value;
        customData.value.sequenceIds = sequenceIds.value;

        api.post(customData.value.button.dataDestUrl, customData.value).then(res => {
          ElMessage.success(res.message);
          customVisible.value = false;
          dataTable.value.findPage();
          editLoading.value = false;
        }).catch(() => {
          editLoading.value = false;
        });
      }).catch(() => {});
    } else {
      ElMessage.error('数据录入不正确，请重新检查！');
    }
  })
};

const getTreeData = (type, nodes) => {
  if (!type) {
    return nodes.map(item => item.id);
  }

  const data = {folderIds: []};
  data[type + 'Ids'] = [];
  nodes.forEach(node => {
    if (node.type === 'folder') {
      data.folderIds.push(node.id);
    } else if (node.type === type) {
      data[type + 'Ids'].push(node.id);
    }
  });
  return data;
}

const loadData = () => {
  loadSubsystem();
  loadModelTree();
  loadScriptTree();
  loadViewTree();
  loadPageTree();
  loadDictionaryTree();
  loadSequence();
  loadFlow();
};

const loadSubsystem = () => {
  api.post('/system/subsystem/queryList').then(res => {
    subsystemList.value = (res.data || []).sort((a, b) => b.name.localeCompare(a.name));
  });
};

const loadModelTree = async() => {
  modelLoading.value = true;
  modelTreeData.value = await loadTreeData('/system/dataModel/queryTree');
  modelLoading.value = false;
};

const loadScriptTree = async() => {
  scriptLoading.value = true;
  scriptTreeData.value = await loadTreeData('/system/scriptGroovy/queryTree');
  scriptLoading.value = false;
};

const loadViewTree = async() => {
  viewLoading.value = true;
  viewTreeData.value = await loadTreeData('/system/view/queryTree');
  viewLoading.value = false;
};

const loadPageTree = async() => {
  pageLoading.value = true;
  pageTreeData.value = await loadTreeData('/system/page/queryTree');
  pageLoading.value = false;
};

const loadDictionaryTree = async() => {
  dictionaryLoading.value = true;
  dictionaryTreeData.value = await loadTreeData('/system/dictionary/queryTree');
  dictionaryLoading.value = false;
};

const loadSequence = async() => {
  sequenceLoading.value = true;
  sequenceData.value = (await api.post('/system/sequence/queryList')).data || [];
  sequenceLoading.value = false;
};

const loadFlow = async() => {
  flowLoading.value = true;
  flowData.value = (await api.post('/system/flow/queryList')).data || [];
  flowLoading.value = false;
};

const loadTreeData = async(url) => {
  const res = await api.post(url);
  return res.data && res.data.children;
};
</script>

<style scoped>
.tree :deep(.el-tree-node__content) {
  height: 30px;

  .node-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    width: 100%;
    .icon {
      display: flex;
      align-items: center;
    }
    .node-label {
      margin-left: 5px;
      flex-grow: 1;
      width: 1px;
      text-overflow: ellipsis;
      overflow: hidden;
      display: flex;

      > span {
        width: 100%;
        text-overflow: ellipsis;
        overflow: hidden;
      }
    }
  }
}
</style>